/***************************************************************************
 *   Copyright © 2010 by Nikolay Kornaev                                   *
 *   n.kornaev@gmail.com                                                   *
 *                                                                         *
 *                    This file is part of neuma.                          *
 *                                                                         *
 *   neuma is free software; you can redistribute it and/or modify it      *
 *   under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   neuma is distributed in the hope that it will be useful,              *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 ***************************************************************************/

#pragma once

#include <QtCore/QMap>
#include <QtCore/QSettings>
#include <QtCore/QVariant>

#include "utils.h"

namespace Neuma
{
  //! Перечисление настроек программы.
  /*!
   * Перечисление всех настроек программы neuma.
   * Собраны в одном месте для исключения ошибок в написании.
   */
  enum SettingName
  {
    PageMarginBottom, /*!< нижнее поле страницы */
    PageMarginLeft, /*!< левое поле страницы */
    PageMarginRight, /*!< правое поле страницы */
    PageMarginTop, /*!< верхнее поле страницы */
    PageOrientation, /*!< ориентация страницы (QPrinter::PageOrientation) */
    PageSize, /*!< размер страницы (QPrinter::PaperSize) */
    RendererExportResolution, /*!< разрешение (dpi) экспорта графики */
    RendererFontColorNeuma, /*!< цвет отрисовки невм */
    RendererFontColorMarks, /*!< цвет отрисовки помет */
    RendererFontColorSyllabe, /*!< цвет отрисовки слогов */
    RendererFontNameNeuma, /*!< имя шрифта отрисовки невм */
    RendererFontNameSyllabe, /*!< имя шрифта отрисовки слогов */
    RendererFontSizeNeuma, /*!< размер шрифта отрисовки невм */
    RendererFontSizeSyllabe, /*!< размер шрифта отрисовки слогов */
    RendererFontsListNeuma, /*!< список использовавшихся имён шрифтов отрисовки невм */
    RendererFontsListSyllabe, /*!< список использовавшихся имён шрифтов отрисовки слогов */
    RendererSpaceBlocksHorizontal, /*!< расстояние (мм) между соседними невмами (и соседними слогами) */
    RendererSpaceBlocksVertical, /*!< расстояние (мм) между невмой и соответствующим слогом */
    RendererSpaceLines, /*!< расстояние (мм) между слогом и невмой следующей строки */
    RendererOutlinePage, /*!< нужна ли обводка области рисования */
    RendererOutlineNeuma, /*!< нужна ли обводка блоков невм */
    RendererOutlineSyllabe, /*!< нужна ли обводка блоков слогов */
    RendererOutlineColorPage, /*!< цвет обводки области рисования */
    RendererOutlineColorNeuma, /*!< цвет обводки блоков невм */
    RendererOutlineColorSyllabe, /*!< цвет обводки блоков слогов */
    RendererNeumaOverSyllabe,  /*!< выравнивать ли центр невмы над центром гласной слога */
    RendererNeumaTruncateMarks  /*!< учитывать ли крайние пометы при выравнивании */
  };
  //! Класс, представляющий состояние одной опции.
  class Setting
  {
  public:
   //! Конструктор.
  /*!
   * Конструктор, создающий новый экземпляр с заданными параметрами.
   * \param path путь сохранения опции.
   * \param defValue значение по умолчанию.
   * \sa setValue()
   */
    Setting(const QString path, const QVariant &defValue) :
      _path(path), _defValue(defValue)
    {
    }
    //! Возвращает связанное с этой опцией значение по-умолчанию.
    QVariant getDefValue() const
    {
      return _defValue;
    }
    //! Возвращает путь сохранения этой опции.
    QString getPath() const
    {
      return _path;
    }
    //! Возвращает значение этой опции.
    QVariant getValue() const
    {
      return _value;
    }
    //! Устанавливает значение опции.
    void setValue(QVariant value)
    {
      _value = value;
    }

  private:
    QString _path;
    QVariant _defValue;
    QVariant _value;
  };

  //! Класс,описывающий все опции программы.
  class SettingsHandler
  {
  public:
    //! Конструктор по-умолчанию.
    /*!
     * При создании экземпляра класса все опции в нём заполняются значениями,
     * никакая другая подготовка не требуется.
     */
    SettingsHandler();

    //! Возвращает значение опции по её имени
    QVariant val(const SettingName name) const;
    //! Устанавливает значение опции по её имени
    void setVal(const SettingName name, const QVariant val);
    //! Сохраняет текущие значения опций
    void writeSettings();

  private:
    QSettings _set;
    QMap<SettingName, Setting *> _data;

    void init();
    void insert(const SettingName name, const QString path, const QVariant defVal);
  };
}
